/*
目前主流的打印机控制语言只要有三种：
Epson公司的ESC命令集（普通打印机）
HP公司的PCL命令集
Adobe公司的PostScript(简称PS)命令集
其它：CPCL命令集（移动打印机）, TSPL命令集(标签打印机)

普通打印机都是ESC指令集
标签打印机这种是TSPL指令集
移动打印机CPCL打印语言

 */
import 'package:xsdk_flutter/xsdk/utils/x_utils_number.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_string.dart';

abstract class XBasePrintCommandUtils {

  //ESC心跳包命令(获取设备状态命令,作为心跳包使用),使用:判断isHeartbeatCommand赋值给message_bluetooth_write_bytes
  // List<int> command_heartbeatPacket_esc =[16,4,1}; 实测也可以
  static const List<int> command_heartbeatPacket_esc =[16,4,2];
  //TSPL心跳包命令(获取设备状态命令,作为心跳包使用),使用:判断isHeartbeatCommand赋值给message_bluetooth_write_bytes
  static const List<int> command_heartbeatPacket_tspl =[27,33,63]; //实测快麦标签没返回
  //CPCL心跳包命令(获取设备状态命令,作为心跳包使用),使用:判断isHeartbeatCommand赋值给message_bluetooth_write_bytes
  static const List<int> command_heartbeatPacket_cpcl =[27,104];

  /*
  ESC打开钱箱命令
  [命令]
  ASCII 码 ESC p m t1 t2
  十六进制码 1B 70 m t1 t2
  十进制码 27 112 m t1 t2
  [范围]m = 0, 1, 48, 49 0 ≤ t1 ≤ 255, 0 ≤ t2 ≤ 255
  [描述]输出由 t1 和 t2 设定的钱箱开启脉冲到由 m 指定的引脚： M 连接引脚 0, 48 钱箱 插座的引脚 2 1, 49 钱箱插座的引脚 5
  [注释] • 钱箱开启脉冲高电平时间为[t1 × 2 ms]，低点平时间为[t2 × 2 ms]。 • 如果 t2 < t1，低电平时间为[t1 × 2 ms]。
  */
  static const List<int> command_openCashDrawer_esc =[27,112,48,49,49];
  static const List<int> command_openCashDrawer_esc2 =[27,112,49,49,49];



  //标签打印机TSPL////////////////////////////////////////////////////////////

  /*
    1mm等于多少dot
    200 DPI: 1 mm = 8 dots
    300 DPI: 1 mm = 12 dots
     */
  static int dot1MM(int printerDPI){
    if (printerDPI>=300){
      return 12;
    }
    //dpi=200
    return 8;
  }

  //指定字体大小的一行字符的GBK编码byte数组长度,
  //200DPI,40mm宽->40*8=320点->24点/中文字 12点/英文-> 320/12 =26英文,即gbk byte长度
  static int getLabelCustomTextSizeOneLineStringGBKBytesLength(int printerDPI,int labelSizeWidth,int textSize){
    //标签总宽度dot,默认用1mm处开始
    int labelTotalDots=labelSizeWidth*dot1MM(printerDPI);

    //1个中文字体的宽度/高度
    int oneChineseCharWidthOrHeightDots=getLabelChineseCharTextWidthOrHeightDots(textSize);

    //1个英文数字占的dot
    int oneEnglishCharDots=XNumberUtils.d2int_floor(oneChineseCharWidthOrHeightDots/2);

    //
    return XNumberUtils.d2int_floor(labelTotalDots/oneEnglishCharDots);

  }

  //一个中文字体的宽度/高度占的dots,这里使用的通用中文字体是TSS24.BF2(24*24 dot),其他tts16/20/32有些打印机不支持
  static int getLabelChineseCharTextWidthOrHeightDots(int textSize){
    int oneChineseCharWidthOrHeight=0;

    if (textSize==1){
      oneChineseCharWidthOrHeight=24*2;
    }else if (textSize==2){
      oneChineseCharWidthOrHeight=24*3;
    }else{
      oneChineseCharWidthOrHeight=24;
    }

    return oneChineseCharWidthOrHeight;
  }


  //标签条码高度,中文字体是TSS24.BF2
  static int getLabelBarcodeHeightDots(
      bool isBarcodeMaxHeight,
      bool isShowBarcodeText
      )
  {
    int barcodeHeight=0;
    if (isBarcodeMaxHeight){
      //大
      barcodeHeight=96;
    }else{
      //标准大小
      barcodeHeight=48;
    }

    if (isShowBarcodeText){
      //显示barcode
      barcodeHeight+=24;
    }

    return barcodeHeight;
  }

  //标签二维码高度
  static int getLabelQrcodeHeightDots(bool isQrcodeMaxHeight){
    int qrcodeHeight=0;
    if (isQrcodeMaxHeight){
      //大,8
      qrcodeHeight=92*2;
    }else{
      //标准大小,4
      qrcodeHeight=92;
    }

    return qrcodeHeight;
  }

  //小票打印机ESC////////////////////////////////////////////////////////////

  //获得指定字符串的GBK编码byte长度
  static int getBytesLength_GBK(String? msg) {
    if (msg==null){
      return 0;
    }
    return XStringUtils.stringToUint8List_gbk(msg).length;
  }


  //指定字体大小的一行字符的GBK编码byte数组长度
  static int getPaperCustomTextSizeOneLineStringGBKBytesLength(int paperSize,int textSize){

    if (textSize==1){

      //58mm,放大1倍的字体,一行8个中文字(数字字母16个)对应gbk编码bytes数组长度为16
      int bytesLengthOfDefaultTextInLine = 16;

      if (paperSize==80){
        //80mm,放大1倍的字体,一行12个中文字(数字字母24个)对应gbk编码bytes数组长度为24
        bytesLengthOfDefaultTextInLine=24;
      }

      return bytesLengthOfDefaultTextInLine;


    }else if (textSize==2){
      //放大2倍的字体

      //58mm,放大1倍的字体,一行5个中文字(数字字母10个)对应gbk编码bytes数组长度为10
      int bytesLengthOfDefaultTextInLine = 10;

      if (paperSize==80){
        //80mm,放大1倍的字体,一行8个中文字(数字字母16个)对应gbk编码bytes数组长度为16
        bytesLengthOfDefaultTextInLine=16;
      }

      return bytesLengthOfDefaultTextInLine;

    }

    //默认字体大小
    return getPaperDefaultTextSizeOneLineStringGBKBytesLength(paperSize);
  }


  /*
    获得对应纸张大小的标准默认字体的一行字符的GBK编码byte数组长度
    参数:
    int paperSize获得纸张大小: 58mm或80mm

     */
  static int getPaperDefaultTextSizeOneLineStringGBKBytesLength(int paperSize){

    //58mm,默认字体大小,一行16个中文字(数字字母32个)对应gbk编码bytes数组长度为32
    int bytesLengthOfDefaultTextInLine = 32;

    if (paperSize==80){
      //80mm,默认字体大小,一行24个中文字(数字字母48个)对应gbk编码bytes数组长度为48
      bytesLengthOfDefaultTextInLine=48;
    }

    return bytesLengthOfDefaultTextInLine;
  }





  ///////////////////////////////////////////////////////////


  /*
    使单行文字居中对齐,在文字左边补空格(注意:一行文字不要超过纸张一行的字数)
    也可使用命令方式:PrintCommand_Text_Align_justification,
    当打印机不支持命令时,可选择使用添加空格方式对齐
    参数:
    int paperSize获得纸张大小: 58mm或80mm
     */
  static String getCenterAlignSpaceForPaper(int paperSize,String str){

    //一行字的gbk编码byte数组的长度
    int bytesLengthOfDefaultTextInLine= getPaperDefaultTextSizeOneLineStringGBKBytesLength(paperSize);

    int center = XNumberUtils.d2int_floor((bytesLengthOfDefaultTextInLine-getBytesLength_GBK(str))/2);
    if (center>0){
      StringBuffer sb=StringBuffer();
      for (int i = 0; i<center; i++){
        sb.write(" ");
      }
      return sb.toString();
    }
    return "";
  }


  /*
    使单行文字居右对齐,在文字左边补空格(注意:一行文字不要超过纸张一行的字数)
    也可使用命令方式:PrintCommand_Text_Align_justification,
    当打印机不支持命令时,可选择使用添加空格方式对齐
    参数:
    int paperSize获得纸张大小: 58mm或80mm
     */
  static String getRightAlignSpaceForPaper(String str,int paperSize){

    //一行字的gbk编码byte数组的长度
    int bytesLengthOfDefaultTextInLine= getPaperDefaultTextSizeOneLineStringGBKBytesLength(paperSize);

    int right = bytesLengthOfDefaultTextInLine-getBytesLength_GBK(str);
    if (right>0){
      StringBuffer sb=StringBuffer();
      for (int i = 0; i<right; i++){
        sb.write(" ");
      }
      return sb.toString();
    }
    return "";
  }

  /*
    使2部分文字左右对齐,在中间补空格(注意:文字总长度不要超过纸张一行的字数)
    参数:
    int paperSize获得纸张大小: 58mm或80mm
     */
  static String getLeftRightAlignSpaceForPaper(String left,String right,int paperSize){

    //一行字的gbk编码byte数组的长度
    int bytesLengthOfDefaultTextInLine= getPaperDefaultTextSizeOneLineStringGBKBytesLength(paperSize);


    int leftStrLength = getBytesLength_GBK(left);
    int rightStrLength = getBytesLength_GBK(right);
    int centerSpace=bytesLengthOfDefaultTextInLine-leftStrLength-rightStrLength;

    if (centerSpace>0){
      StringBuffer sb=StringBuffer();
      for (int i = 0; i<centerSpace; i++){
        sb.write(" ");
      }
      return sb.toString();
    }

    return "";

  }




}
